home *** CD-ROM | disk | FTP | other *** search
- /*
- TransSkel multiple-window demonstration: Region module
-
- This module handles a window in which the mouse may be clicked and
- dragged to draw rectangles. The rects so drawn are combined into
- a single region, the outline of which is drawn. Rects drawn while
- the shift key is held down are subtracted from the region.
- Double-clicking the mouse clears the display. If the window is
- resized, the region that is drawn is resized as well.
-
- 14 June 1986 Paul DuBois
-
- Changes:
- 07/08/86 Changed outline so that it's drawn as a marquee.
- */
-
- # include "MultiSkel.h"
-
-
- WindowPtr rgnWind;
- Rect rgnPortRect; /* portRect size - for detecting wind grows */
- RgnHandle selectRgn; /* current region to be drawn */
- long selectWhen; /* time of last click */
- Point selectWhere; /* location of last click */
-
- Pattern marqueePat = { 0x0f, 0x87, 0xc3, 0xe1, 0xf0, 0x78, 0x3c, 0x1e };
-
-
- static Clobber ()
- {
- DisposeRgn (selectRgn);
- CloseWindow (rgnWind);
- }
-
-
- /*
- On double-click, clear window. On single click, draw gray selection
- rectangle as long as mouse is held down. If user draws non-empty rect,
- then add it to the selection region and redraw the region's outline.
- If the shift-key was down, then subtract the selection region instead
- and redraw.
- */
-
-
- static Mouse (thePt, t, mods)
- Point thePt;
- long t;
- int mods;
-
- {
- Rect r;
- RgnHandle rgn;
-
- r = rgnWind->portRect;
- if (thePt.h >= r.right - 15) /* must not click in right edge */
- return;
- if (t - selectWhen <= GetDblTime ()) /* it's a double-click */
- {
- selectWhen = 0L; /* don't take next click as dbl-click */
- SetWindClip (rgnWind);
- EraseRgn (selectRgn);
- ResetWindClip ();
- SetEmptyRgn (selectRgn); /* clear region */
- }
- else
- {
- selectWhen = t; /* update click variables */
- selectWhere = thePt;
- DoSelectRect (thePt, &r); /* draw selection rectangle */
- if (!EmptyRect (&r))
- {
- EraseRgn (selectRgn);
- selectWhen = 0L;
- rgn = NewRgn ();
- RectRgn (rgn, &r);
- if ((mods & shiftKey) != 0) /* test shift key */
- DiffRgn (selectRgn, rgn, selectRgn);
- else
- UnionRgn (selectRgn, rgn, selectRgn);
- DisposeRgn (rgn);
- }
- }
- }
-
-
- /*
- Redraw the current region. If the window was resized, resize
- the region to fit.
- */
-
- static Update (resized)
- Boolean resized;
- {
- Rect r;
-
- EraseRect (&rgnWind->portRect);
- if (resized)
- {
- r = rgnWind->portRect;
- rgnPortRect.right -= 15; /* don't use right edge of window */
- r.right -= 15;
- MapRgn (selectRgn, &rgnPortRect, &r);
- rgnPortRect = rgnWind->portRect;
- }
- DrawGrowBox (rgnWind);
- Idle ();
- }
-
-
- static Activate (active)
- Boolean active;
- {
- DrawGrowBox (rgnWind);
- if (active)
- DisableItem (editMenu, 0);
- else
- EnableItem (editMenu, 0);
- DrawMenuBar ();
- }
-
-
- MarqueeRgn (r)
- RgnHandle r;
- {
- PenState p;
- Byte b;
- int i;
-
- GetPenState (&p);
- PenPat (marqueePat);
- PenMode (patCopy);
- FrameRgn (r);
- SetPenState (&p);
- b = marqueePat[0]; /* shift pattern for next call */
- for (i = 0; i < 7; ++i)
- marqueePat[i] = marqueePat[i+1];
- marqueePat[7] = b;
- }
-
-
- static Idle ()
- {
- int i;
-
- SetWindClip (rgnWind);
- MarqueeRgn (selectRgn); /* draw selection region outline */
- ResetWindClip (); /* restore previous clipping */
- }
-
- /*
- While mouse is down, draw gray selection rectangle in the current
- port. Return the resultant rect in dstRect. The rect is always
- clipped to the current portRect.
- */
-
- DoSelectRect (startPoint, dstRect)
- Point startPoint;
- Rect *dstRect;
- {
- Point pt, dragPt;
- Rect rClip;
- GrafPtr thePort;
- Boolean result;
- PenState ps;
- int i;
-
- GetPort (&thePort);
- rClip = thePort->portRect;
- rClip.right -= 15;
- GetPenState (&ps);
- PenPat (gray);
- PenMode (patXor);
- dragPt = startPoint;
- Pt2Rect (dragPt, dragPt, dstRect);
- FrameRect (dstRect);
- for (;;)
- {
- GetMouse (&pt);
- if (!EqualPt (pt, dragPt)) /* mouse has moved, change region */
- {
- FrameRect (dstRect);
- dragPt = pt;
- Pt2Rect (dragPt, startPoint, dstRect);
- result = SectRect (dstRect, &rClip, dstRect);
- FrameRect (dstRect);
- for (i = 0; i < 1000; ++i) { /* empty */ }
- }
- if (!StillDown ()) break;
- }
- FrameRect (dstRect); /* erase last rect */
- SetPenState (&ps);
- }
-
-
-
- RgnWindInit ()
- {
- rgnWind = GetNewWindow (rgnWindRes, nil, -1L);
- SkelWindow (rgnWind,
- Mouse, /* draw rectangles */
- nil, /* ignore keyclicks */
- Update,
- Activate,
- nil, /* no close proc */
- Clobber, /* disposal proc */
- Idle, /* idle proc */
- true);
-
- rgnPortRect = rgnWind->portRect;
- selectRgn = NewRgn (); /* selected region empty initially */
- selectWhen = 0L; /* first click can't be taken as dbl-click */
- }
-